﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace MusicPlayer
{
    class PlayList : IPlayList, INotifyPropertyChanged
    {
        public event EventHandler<EventArgs> OnSongListChange;
        public event PropertyChangedEventHandler PropertyChanged;

        public Song SelectedSong
        {
            get;
            set;
        }

        private List<Song> songList;

        //private int currentIndex = 0;
        private int currentSelectedIndex = 0;

        private IOrder orderer;

        public List<Song> Songs
        {
            get { return songList; }
            private set { this.songList = value; }
        }

        public PlayList()
        {
            songList = new List<Song>();

            orderer = new OrderDefault();
        }

        public string GetPrevSongToPlay()
        {
            int nextIndex = orderer.GetPrevToPlay(currentSelectedIndex, songList.Count);
            currentSelectedIndex = nextIndex;

            this.SelectedSong = this.Songs[currentSelectedIndex];
            this.NotifyPropertyChanged("SelectedSong");

            return songList[nextIndex].Location;
        }

        public string GetNextSongToPlay()
        {
            int prevIndex = orderer.GetNextToPlay(currentSelectedIndex, songList.Count);
            currentSelectedIndex = prevIndex;

            this.SelectedSong = this.Songs[currentSelectedIndex];
            this.NotifyPropertyChanged("SelectedSong");

            return songList[prevIndex].Location;
        }

        public string GetCurrentSongToPlay()
        {
            if (songList.Count != 0)
            {
                this.SelectedSong = this.songList[currentSelectedIndex];
                this.NotifyPropertyChanged("SelectedSong");

                return songList[currentSelectedIndex].Location;
            }
            else
            {
                return null;
            }
        }

        public void AddInputHandler(IPlayListCommands handler)
        {
            //Subscribe to all events we need to handle
            handler.OnClear += handler_OnClear;
            handler.OnSortFiles += handler_OnSortFiles;
            handler.OnAddFiles += handler_OnAddFiles;
            handler.OnOrderChange += handler_OnOrderChange;
            handler.OnCurrentSongChange += handler_OnCurrentSongChange;
        }

        void handler_OnCurrentSongChange(object sender, CurrentSongArgs e)
        {
            this.currentSelectedIndex = e.CurrentIndex;
        }

        void handler_OnOrderChange(object sender, PlayListOrderArgs e)
        {
            switch (e.Order)
            {
                case "Default":
                    {
                        this.orderer = new OrderDefault();
                        break;
                    }
                case "Repeat":
                    {
                        this.orderer = new OrderRepeat();
                        break;
                    }
                case "Random":
                    {
                        this.orderer = new OrderRandom();
                        break;
                    }
            }
        }

        void handler_OnAddFiles(object sender, EventArgs e)
        {
            ModifierPlayList modifier = new ModifierAddFiles();
            modifier.DoOperation(songList);
            OnSongListChange(this, null);
        }

        void handler_OnSortFiles(object sender, EventArgs e)
        {
            ModifierPlayList modifier = new  ModifierSortList();
            modifier.DoOperation(songList);
            OnSongListChange(this, null);
        }

        void handler_OnClear(object sender, EventArgs e)
        {
            ModifierPlayList modifier = new ModifierClearList();
            modifier.DoOperation(songList);
            OnSongListChange(this, null);
        }

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }  
    }
}
